﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;
using System.Linq.Expressions;

namespace FinalProject.Data.Sort
{
    public static class QueryExtensions
    {
        public static IOrderedQueryable<T> OrderBy<T>(this IQueryable<T> source,
            string orderByProperty,
            bool desc) where T : class
        {
            string command = desc ? "OrderByDescending" : "OrderBy";
            var type = typeof(T);
            var property = type.GetProperty(orderByProperty, BindingFlags.Public | BindingFlags.Static | BindingFlags.Instance | BindingFlags.IgnoreCase);
            var parameter = Expression.Parameter(type, "p");
            var propertyAccess = Expression.MakeMemberAccess(parameter, property);
            var orderByExpression = Expression.Lambda(propertyAccess, parameter);
            var resultExpression = Expression.Call(typeof(Queryable), command, new Type[] { type, property.PropertyType }, source.Expression, Expression.Quote(orderByExpression));
            return (IOrderedQueryable<T>)source.Provider.CreateQuery<T>(resultExpression);
        }

        public static IOrderedQueryable<T> ThenBy<T>(this IQueryable<T> source,
            string orderByProperty,
            bool desc) where T : class
        {
            string command = desc ? "ThenByDescending" : "ThenBy";
            var type = typeof(T);
            var property = type.GetProperty(orderByProperty, BindingFlags.Public | BindingFlags.Static | BindingFlags.Instance | BindingFlags.IgnoreCase);
            var parameter = Expression.Parameter(type, "p");
            var propertyAccess = Expression.MakeMemberAccess(parameter, property);
            var orderByExpression = Expression.Lambda(propertyAccess, parameter);
            var resultExpression = Expression.Call(typeof(Queryable), command, new Type[] { type, property.PropertyType }, source.Expression, Expression.Quote(orderByExpression));
            return (IOrderedQueryable<T>)source.Provider.CreateQuery<T>(resultExpression);

        }
    }
}
